package com.hudson.plugin.server.hibernateDB.internal.domain.dao;

import com.hudson.plugin.server.hibernateDB.domain.dao.BuildsDAOInterface;
import com.hudson.plugin.server.hibernateDB.internal.domain.entity.BuildsEntity;
import com.hudson.plugin.server.hibernateDB.internal.domain.entity.ProjectsEntity;
import org.hibernate.LockMode;
import org.hibernate.Query;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import java.util.ArrayList;
import java.util.List;

/**
 * A data access object (DAO) providing persistence and search support for
 * Builds entities. Transaction control of the save(), update() and delete()
 * operations can directly support Spring container-managed transactions or they
 * can be augmented to handle user-managed Spring transactions. Each of these
 * methods provides additional information for how to configure it for the
 * desired type of transaction control.
 *
 * @author MyEclipse Persistence Tools
 * @see .Builds
 */

public class BuildsDAO extends HibernateDaoSupport implements BuildsDAOInterface {
    private static final Logger log = LoggerFactory.getLogger(BuildsDAO.class);

    protected void initDao() {
        // do nothing
    }

    public void save(BuildsEntity transientInstance) {
        log.debug("saving Builds instance");
        try {
            getHibernateTemplate().save(transientInstance);
            log.debug("save successful");
        } catch (RuntimeException re) {
            log.error("save failed", re);
            throw re;
        }
    }

    public void delete(BuildsEntity persistentInstance) {
        log.debug("deleting Builds instance");
        try {
            getHibernateTemplate().delete(persistentInstance);
            log.debug("delete successful");
        } catch (RuntimeException re) {
            log.error("delete failed", re);
            throw re;
        }
    }

    public BuildsEntity findById(Integer id) {
        log.debug("getting Builds instance with id: " + id);
        try {
            BuildsEntity instance = (BuildsEntity) getHibernateTemplate().load(BuildsEntity.class, id);
            return instance;
        } catch (RuntimeException re) {
            log.error("get failed", re);
            throw re;
        }
    }

    public List findByExample(BuildsEntity instance) {
        log.debug("finding Builds instance by example");
        try {
            List results = getHibernateTemplate().findByExample(instance);
            log.debug("find by example successful, result size: "
                    + results.size());
            if (results == null) {
                return new ArrayList();
            }
            return results;
        } catch (RuntimeException re) {
            log.error("find by example failed", re);
            throw re;
        }
    }

    public List findByProperty(String propertyName, Object value) {
        log.debug("finding Builds instance with property: " + propertyName
                + ", value: " + value);
        try {
            String queryString = "from BuildsEntity as model where model." + propertyName + " = ?";
            List results = getHibernateTemplate().find(queryString, value);
            if (results == null) {
                return new ArrayList();
            }
            return results;
        } catch (RuntimeException re) {
            log.error("find by property name failed", re);
            throw re;
        }
    }

    public List findByBuildNum(Object buildNum) {
        return findByProperty(BUILD_NUM, buildNum);
    }

    public List findByCauseAction(Object causeAction) {
        return findByProperty(CAUSE_ACTION, causeAction);
    }

    public List findByAuthor(Object author) {
        return findByProperty(AUTHOR, author);
    }

    public List findByResult(Object result) {
        return findByProperty(RESULT, result);
    }

    public List findByDuration(Object duration) {
        return findByProperty(DURATION, duration);
    }

    public List findByBuildOn(Object buildOn) {
        return findByProperty(BUILD_ON, buildOn);
    }

    public List findByFailCount(Object failCount) {
        return findByProperty(FAIL_COUNT, failCount);
    }

    public List findBySkipCount(Object skipCount) {
        return findByProperty(SKIP_COUNT, skipCount);
    }

    public List findByTotalCount(Object totalCount) {
        return findByProperty(TOTAL_COUNT, totalCount);
    }

    public List findAll() {
        log.debug("finding all Builds instances");
        try {
            String queryString = "from BuildsEntity";
            List results = getHibernateTemplate().find(queryString);
            if (results == null) {
                return new ArrayList();
            }
            return results;
        } catch (RuntimeException re) {
            log.error("find all failed", re);
            throw re;
        }
    }

    public BuildsEntity merge(BuildsEntity detachedInstance) {
        log.debug("merging Builds instance");
        try {
            BuildsEntity result = (BuildsEntity) getHibernateTemplate().merge(
                    detachedInstance);
            log.debug("merge successful");
            getHibernateTemplate().flush();
            this.getSession().flush();
            return result;
        } catch (RuntimeException re) {
            log.error("merge failed", re);
            throw re;
        }
    }

    public void attachDirty(BuildsEntity instance) {
        log.debug("attaching dirty Builds instance");
        try {
            getHibernateTemplate().saveOrUpdate(instance);
            log.debug("attach successful");
        } catch (RuntimeException re) {
            log.error("attach failed", re);
            throw re;
        }
    }

    public void attachClean(BuildsEntity instance) {
        log.debug("attaching clean Builds instance");
        try {
            getHibernateTemplate().lock(instance, LockMode.NONE);
            log.debug("attach successful");
        } catch (RuntimeException re) {
            log.error("attach failed", re);
            throw re;
        }
    }

    public static BuildsDAOInterface getFromApplicationContext(ApplicationContext ctx) {
        return (BuildsDAOInterface) ctx.getBean("BuildsDAO");
    }

    public List<String> findProjectAllBuildsNumber(ProjectsEntity projectsEntity) {
        log.debug("finding Project All BuildsNumber");
        try {
            Query query = this.getSession().createQuery("select b.buildNum from BuildsEntity b where b.projectsByProjectId.id = :project_id");
            query.setParameter("project_id", projectsEntity.getId());
            List<String> builds = query.list();
            if (builds == null) {
                return new ArrayList();
            }
            return builds;
        } catch (RuntimeException re) {
            log.error("find Project All BuildsNumber failed ", re);
            throw re;
        }
    }


    public List<Integer> findBuildsByProjectIdAndBuildNumber(Integer projectId, String buildNum) {
        log.debug("finding Builds By ProjectId And BuildNumber");
        try {
            Query query = this.getSession().createQuery("select b.id from BuildsEntity b where b.projectsByProjectId.id = :project_id and b.buildNum = :build_num");
            query.setParameter("project_id", projectId);
            query.setParameter("build_num", Integer.parseInt(buildNum));
            List<Integer> builds = query.list();

            if (builds == null) {
                return new ArrayList();
            }
            return builds;
        } catch (RuntimeException re) {
            log.error("finding Builds By ProjectId And BuildNumber failed ", re);
            throw re;
        }
    }


}